module.exports = function() {
  this.async2sync = function(fn, modifyThis = null) {
    // 用于存储回调函数，该函数复用于所有用于helper处理的异步函数
    // 关键就在于这里，feed 其实就是异步的回调函数；
    // 通过 helper(asyncFun), 此时的回调函数形式是错误的，而且 feed 是undefined；
    // 但是当调用回调函数时，本次轮回结束，导致 feed 就有值了，所以 ddd 中的 feed.apply 可以正确执行；
    // 也就得到了正确的结果；
    var feed;
    /**
     * 执行次序分析：
     *    helper的参数fn是一个异步函数，通过helper的处理，返回一个含有内部处理逻辑
     *    的函数，该函数封装了所需参数和可能的回调函数feed，并且返回一个设置feed的函数。
     *
     *    在具体的使用中，通过helper函数封装fs.readFile，获取readFile。当执行第一个
     *    片段时，首先将所有的参数（包括feed）合并到args，并执行异步调用返回处理函数；此时
     *    我们用获取的返回函数设置回调函数，进而影响到args中的最后一项的函数
     */

    return function aaa(){
      var args = [].slice.call(arguments);

      args.push(function ddd(){
        if(feed) {
          // console.log(feed); // [Function: ccc]
          feed.apply(null,arguments);
        }
        //console.log(feed)
      });
      fn.apply(modifyThis ? modifyThis : null, args);
      // console.log('fn执行中');
      // 返回一个函数，用于给yield之前的变量赋值
      return function bbb(fn){
        feed = fn;
      }
    }
  };

  // gfn：生成器函数；
  // index：如果是数字，是希望得到第几个参数；如果是true，得到所有有用的值；
  this.sync = function(gfn, index = 1) {
    var generator = gfn();
    next();

    function next(data){
      // console.log('next--data');
      // console.log(typeof data);
      generator.ret = generator.next(data);
      // console.log(generator.ret);
      // console.log(generator.ret.value);// [Function: bbb]
      if(generator.ret.done){
        return;
      }
      generator.ret.value(
        // function ccc(error, res, d){
        function ccc(){
          // console.log('ccc');
          console.log(arguments.length);
          if(arguments[0])
            throw arguments[0];
          // console.log('error', error);
          // console.log('d', d);
          
          // console.log(index);
          if (index === true) {
            let obj = {};
            for (var i = 1; i < arguments.length; i++) {
              obj["index" + i] = arguments[i];
            }
            console.log(obj);
            console.log(typeof obj);
            next.apply(null, [obj]);
          } else {
            next.apply(null, [].slice.call(arguments, index, index + 1));
          }
        }
      );
    }
  };
};